package graphics;

import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

import tool.ScreenUtils;

import function.search.EventListener;

public class SearchChoiceInput2 {

	private static final int MAX_WIDTH = 210;
	protected static int X_SEARCH_TEXT_OFFSET = 20;
	private static int NB_INPUTS_PER_PAGE = 7;

	String[] choices = null;
	int pageIndex = 0;
	private Graphics g = null;
	private int choiceIndex = -1;
	private boolean isAllModeEngaged;

	private EventListener[] listeners;
	private String title;

	public SearchChoiceInput2(String[] someEntries) {
		listeners = new EventListener[10];
		choices = someEntries;
		isAllModeEngaged = false;
	}

	public void repaint(Graphics someGraphics) {
		g = someGraphics;

		g.setColor(BootColor.BLACK);
		g.fillRect(0, 0, 240, 250);

		int nbChoices = getNumberOfChoices();

		int textHeight = g.getFont().getHeight();
		int listOffset = getListOffset();

		if ((severalPages()) && (pageIndex > 0)) {
			g.setColor(Theme.getMenuColor());
			g.drawString("More", 20, listOffset - textHeight, Graphics.LEFT
					| Graphics.TOP);
		}

		for (int i = 0; i < nbChoices; i++) {
			String choice = resize((i + 1) + ". "
					+ choices[i + pageIndex * NB_INPUTS_PER_PAGE]);

			g.setColor(BootColor.WHITE);
			g.drawString(choice, X_SEARCH_TEXT_OFFSET, listOffset + textHeight
					* i, Graphics.LEFT | Graphics.TOP);
		}

		if ((severalPages()) && (!isLastPage())) {

			g.setColor(Theme.getMenuColor());
			g.drawString("More", 20, listOffset + textHeight * nbChoices,
					Graphics.LEFT | Graphics.TOP);
		}
		g.setColor(Theme.getMenuColor());
		if (getPagesNumber() > 1) {
			g.drawString((pageIndex + 1) + "/" + getPagesNumber(), 240,
					listOffset + textHeight * NB_INPUTS_PER_PAGE,
					Graphics.RIGHT | Graphics.TOP);
		}

		if (isLastPage() && isAllModeEngaged) {
			g.setColor(BootColor.FLASHY_MENU_COLOR_2);
			int index = getNumberOfChoices();
			g.drawString((index + 1) + ". All", X_SEARCH_TEXT_OFFSET,
					getListOffset() + g.getFont().getHeight() * index,
					Graphics.LEFT | Graphics.TOP);
		}

		if (title != null) {
			int fHeight = g.getFont().getHeight();
			int tWidth = g.getFont().stringWidth(title);
			int gap = 10;
			g.setColor(BootColor.BLACK);
			g.fillRect((ScreenUtils.SCREEN_WIDTH - tWidth) / 2 - gap,
					(ScreenUtils.SCREEN_HEIGHT - fHeight * 2) / 2 - gap, tWidth + 2
							* gap, fHeight * 2 + gap * 2);
			g.setColor(BootColor.BASIC_MENU_COLOR);
			g.drawRect((ScreenUtils.SCREEN_WIDTH - tWidth) / 2 - gap,
					(ScreenUtils.SCREEN_HEIGHT - fHeight * 2) / 2- gap, tWidth + 2
							* gap, fHeight * 2 + gap * 2);
			g.setColor(BootColor.WHITE);
			g.drawString(title, ScreenUtils.SCREEN_WIDTH / 2,
					(ScreenUtils.SCREEN_HEIGHT - fHeight * 2) / 2, Graphics.TOP
							| Graphics.HCENTER);
			g.setColor(BootColor.BASIC_MENU_COLOR);
			g.drawString("added", ScreenUtils.SCREEN_WIDTH / 2,
					ScreenUtils.SCREEN_HEIGHT / 2, Graphics.TOP
							| Graphics.HCENTER);
		}
	}

	protected int getListOffset() {
		int textHeight = g.getFont().getHeight();
		int listOffset = 3 + textHeight;
		return listOffset;
	}

	private String resize(String rawchoice) {
		Font f = g.getFont();
		String result = rawchoice;
		if (isOneLine(result)) {
			return result;
		}

		while (f.stringWidth(result + " [...]") > MAX_WIDTH) {
			result = result.substring(0, result.lastIndexOf(' '));
		}
		return result + " [...]";
	}

	private boolean isOneLine(String input) {
		Font f = g.getFont();
		return (f.stringWidth(input) < MAX_WIDTH);
	}

	public void keyPressed(int keyCode) {

		if (getPagesNumber() > 1) {
			if ((keyCode == -2) && (!isLastPage())) {
				pageIndex++;
			} else if ((keyCode == -1) && (pageIndex != 0)) {
				pageIndex--;
			}
		}

		int offset = 49;
		int nbChoices = getNumberOfChoices();

		if ((keyCode < offset) || (keyCode > offset + nbChoices)) {
			return;
		}

		if (keyCode - offset == nbChoices) {
			emit(EventListener.EVENT_ALL_SELECTED);
		} else {
			choiceIndex = pageIndex * NB_INPUTS_PER_PAGE + keyCode - offset;
			emit(EventListener.EVENT_PROCESS_DONE);
		}

	}

	private void emit(String event) {
		for (int i = 0; (listeners[i] != null) && (i < listeners.length); i++) {
			listeners[i].processEvent(event);
		}
	}

	private int getPagesNumber() {
		if (choices.length <= NB_INPUTS_PER_PAGE) {
			return 1;
		} else {
			if (choices.length % NB_INPUTS_PER_PAGE == 0) {
				return ((int) choices.length / NB_INPUTS_PER_PAGE);
			} else {
				return ((int) choices.length / NB_INPUTS_PER_PAGE) + 1;
			}
		}
	}

	private boolean severalPages() {
		return getPagesNumber() > 1;
	}

	protected int getNumberOfChoices() {
		if (getPagesNumber() == 1) {
			return choices.length;
		} else if (isLastPage()) {
			if (choices.length % NB_INPUTS_PER_PAGE == 0) {
				return NB_INPUTS_PER_PAGE;
			} else {
				return choices.length % NB_INPUTS_PER_PAGE;
			}
		} else {
			return NB_INPUTS_PER_PAGE;
		}
	}

	private boolean isLastPage() {
		return pageIndex == getPagesNumber() - 1;
	}

	public void gotoLastPage() {
		pageIndex = getPagesNumber() - 1;
	}

	public void addListener(EventListener listener) {
		int i = 0;
		while ((listeners[i] != null) && (i < listeners.length)) {
			i++;
		}
		listeners[i] = listener;
	}

	public String getChoice() {
		return choices[choiceIndex];
	}

	public int getchosenIndex() {
		return choiceIndex;
	}

	public void engageAllMode() {
		isAllModeEngaged = true;
	}

	public void alert(String aTitle) {
		title = aTitle;
		emit(EventListener.EVENT_REPAINT_REQUIRED);
		new Timer().schedule(new TimerTask() {

			public void run() {
				title = null;
				emit(EventListener.EVENT_REPAINT_REQUIRED);
			}
		}, 1000);
	}
}
